<template>
  <div class="app-container">
    <!-- 对话框(添加 / 修改) -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="1400px" v-dialogDrag append-to-body>
      <el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="auto">
        <el-row :gutter="20" type="flex" style="flex-wrap: wrap">
          <el-col :span="6">
            <el-form-item label="来源类型" prop="sourceType">
              <el-select v-model="formData.sourceType" placeholder="请选择来源类型" filterable clearable style="width: 100%"
                @change="handleSourceTypeChange" :disabled="isDetailMode || disabledFields.sourceType">
                <el-option v-for="dict in this.getDictDatas(DICT_TYPE.QUALITY_SOURCE_TYPE)" :key="dict.value"
                  :label="dict.label" :value="parseInt(dict.value)" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="单据日期" prop="orderDate">
              <el-date-picker v-model="formData.orderDate" type="date" placeholder="请选择单据日期" value-format="yyyy-MM-dd"
                style="width: 100%" :disabled="isDetailMode" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="来源单号" prop="sourceNo">
              <el-input v-model="formData.sourceNo" placeholder="请输入来源单号" style="width: 100%"
                :disabled="isDetailMode || disabledFields.sourceNo" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="业务类型" prop="businessType">
              <el-select :disabled="isDetailMode || disabledFields.businessType" v-model="formData.businessType"
                placeholder="请选择业务类型" filterable clearable size="small" style="width: 100%"
                @change="handleBusinessTypeChange">
                <el-option v-for="dict in this.getDictDatas(DICT_TYPE.INBOUND_TYPE)" :key="dict.value"
                  :label="dict.label" :value="parseInt(dict.value)" />
              </el-select>
            </el-form-item>
          </el-col>
          <!--          <el-col :span="6">-->
          <!--            <el-form-item label="出库仓库" prop="outWarehouseId">-->
          <!--              <treeselect v-model="formData.outWarehouseId" :options="warehouseTree" :normalizer="normalizerW"-->
          <!--                          placeholder="选择出库仓库" style="width: 100%" @select="onWarehouseChange"-->
          <!--                          :disabled="isDetailMode"/>-->
          <!--            </el-form-item>-->
          <!--          </el-col>-->
          <!--          <el-col :span="6">-->
          <!--            <el-form-item label="出库库位" prop="outStoreId">-->
          <!--              <el-select v-model="formData.outStoreId" placeholder="请选择出库库位" clearable size="small"-->
          <!--                         style="width: 100%"-->
          <!--                         :disabled="isDetailMode">-->
          <!--                <el-option v-for="location in locationList" :key="location.id" :label="location.storageLocationName"-->
          <!--                           :value="location.id"/>-->
          <!--              </el-select>-->
          <!--            </el-form-item>-->
          <!--          </el-col>-->
          <el-col :span="6">
            <el-form-item label="入库仓库" prop="inWarehouseId">
              <treeselect v-model="formData.inWarehouseId" :options="warehouseTree" :normalizer="normalizerW"
                placeholder="选择入库仓库" style="width: 100%;box-sizing: border-box" @select="onWarehouseInChange"
                :disabled="isDetailMode" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="入库库位" prop="inStoreId">
              <el-select v-model="formData.inStoreId" placeholder="请选择入库库位" clearable size="small" style="width: 100%"
                :disabled="isDetailMode">
                <el-option v-for="location in locationInList" :key="location.id" :label="location.storageLocationName"
                  :value="location.id" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="领料人" prop="applicantUserId">
              <el-select v-model="formData.applicantUserId" placeholder="请选择领料人" filterable style="width: 100%"
                remote :remote-method="applicantRemoteMethod" :loading="applicantUserLoading" 
                @change="handleApplicantChange" :disabled="isDetailMode">
                <el-option v-for="user in applicantUserList" :key="user.id" :label="user.nickname" :value="user.id" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="领料车间" prop="deptId">
              <treeselect v-model="formData.deptId" :options="deptList" :normalizer="normalizer" 
                @select="deptChange" placeholder="选择领料车间" style="width: 100%" :disabled="isDetailMode" />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 物料表格 -->
        <el-form-item label="物料明细" prop="materialList">
          <el-button v-if="!isDetailMode" type="primary" size="mini" @click="addSupply" style="margin-bottom: 10px;">
            <i class="el-icon-plus"></i> 新增物料
          </el-button>
          <el-table :data="formData.materialList" style="width: 100%" border max-height="400px">
            <el-table-column label="序号" type="index" width="80" align="center" />
            <el-table-column label="物料" align="center">
              <template slot-scope="scope">
                <div v-if="isDetailMode">
                  {{ scope.row.materialName || '未选择物料' }}
                </div>
                <el-select v-else v-model="scope.row.materialId" placeholder="请输入物料名称" filterable remote
                  :remote-method="(query) => remoteMethod(query, scope.$index)" :loading="itemLoadingMap[scope.$index]"
                  style="width: 100%" @change="handleMaterialSelect($event, scope.$index)">
                  <el-option v-for="material in (scope.row.materialOptions || [])" :key="material.id"
                    :label="material.materialName" :value="material.id">
                    <span style="float: left">{{ material.materialName }}</span>
                    <span style="float: right; color: #8492a6; font-size: 13px">{{ material.materialNo }}</span>
                  </el-option>
                </el-select>
              </template>
            </el-table-column>
            <el-table-column prop="quantity" label="数量" align="center" width="200">
              <template slot-scope="scope">
                <el-input v-model="scope.row.quantity" placeholder="数量" size="small" align="center"
                  :disabled="isDetailMode" />
              </template>
            </el-table-column>
            <!--            <el-table-column prop="batchNo" label="批次号" align="center">-->
            <!--              <template slot-scope="scope">-->
            <!--                <el-input v-model="scope.row.batchNo" placeholder="请输入批次号" size="small"-->
            <!--                          :disabled="isDetailMode"/>-->
            <!--              </template>-->
            <!--            </el-table-column>-->
            <el-table-column v-if="!isDetailMode" label="操作" width="100" align="center">
              <template slot-scope="scope">
                <el-button type="danger" size="mini" @click="removeSupply(scope.$index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button v-if="!isDetailMode" type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
        <el-button @click="dialogVisible = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import * as OrderApi from '@/api/warehouse/order';
import { getDictDatas, DICT_TYPE } from '@/utils/dict'
import * as WarehouseApi from "@/api/storage/warehouse";
import * as LocationApi from "@/api/storage/location";
import * as UserApi from '@/api/system/user';
import { listDept } from "@/api/system/dept";
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
import * as MaterialApi from "@/api/basic/material";

export default {
  name: "OrderForm",
  components: {
    Treeselect
  },
  data() {
    return {
      // 仓库树数据
      warehouseTree: [],
      // 库位列表
      locationList: [],
      locationInList: [],
      // 弹出层标题
      dialogTitle: "",
      // 是否显示弹出层
      dialogVisible: false,
      // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
      formLoading: false,
      // 表单参数
      // 是否为详情模式
      isDetailMode: false,
      // 禁用字段标记
      disabledFields: {},
      // 部门列表
      deptList: [],
      // 领料人列表
      applicantUserList: [],
      // 领料人加载状态
      applicantUserLoading: false,
      formData: {
        id: undefined,
        orderType: 1,
        orderDate: this.formatDate(new Date()),
        sourceType: undefined,
        sourceTypeName: undefined,
        sourceNo: undefined,
        businessType: undefined,
        businessTypeName: undefined,
        outWarehouseId: undefined,
        outStoreId: undefined,
        inWarehouseId: undefined,
        inStoreId: undefined,
        applicantUserId: undefined,
        applicantUserName: undefined,
        deptId: undefined,
        deptName: undefined,
        materialList: []
      },
      // 表单校验
      formRules: {},
      materialLoading: false,
      // 存储每个物料项的独立加载状态
      itemLoadingMap: {}
    };
  },
  created() {
    this.getWarehouseTree();
  },
  methods: {
    /** 新增：物料远程搜索方法 - 为特定索引的物料项搜索 */
    async remoteMethod(query, index) {
      // 设置该项的加载状态
      this.$set(this.itemLoadingMap, index, true);
      try {
        const params = {
          pageNo: 1,
          pageSize: 100
        };

        // 如果有查询条件，添加到参数中
        if (query) {
          params.materialName = query;
        }

        const res = await MaterialApi.getMaterialPage(params);
        // 为当前物料项设置独立的物料列表
        if (!this.formData.materialList[index]) {
          this.formData.materialList[index] = {};
        }
        this.$set(this.formData.materialList[index], 'materialOptions', res.data.list);
      } catch (error) {
        console.error('获取物料列表失败:', error);
        // 设置空数组作为默认值
        if (this.formData.materialList[index]) {
          this.$set(this.formData.materialList[index], 'materialOptions', []);
        }
      } finally {
        // 清除加载状态
        this.$set(this.itemLoadingMap, index, false);
      }
    },

    /** 处理来源类型变化 */
    handleSourceTypeChange(value) {
      if (value) {
        const dictData = this.getDictDatas(DICT_TYPE.QUALITY_SOURCE_TYPE);
        const selected = dictData.find(item => parseInt(item.value) === value);
        if (selected) {
          this.formData.sourceTypeName = selected.label;
        }
      } else {
        this.formData.sourceTypeName = '';
      }
    },

    /** 处理业务类型变化 */
    handleBusinessTypeChange(value) {
      if (value) {
        const dictData = this.getDictDatas(DICT_TYPE.OUTBOUND_TYPE);
        const selected = dictData.find(item => parseInt(item.value) === value);
        if (selected) {
          this.formData.businessTypeName = selected.label;
        }
      } else {
        this.formData.businessTypeName = '';
      }
    },

    /** 新增：物料选择后处理 */
    async handleMaterialSelect(materialId, index) {
      if (materialId && this.formData.materialList[index] && this.formData.materialList[index].materialOptions) {
        // 从当前项的物料列表中查找选中的物料
        const selectedMaterial = this.formData.materialList[index].materialOptions.find(item => item.id === materialId);
        if (selectedMaterial) {
          // 更新物料相关信息
          this.$set(this.formData.materialList[index], 'materialName', selectedMaterial.materialName);
          this.$set(this.formData.materialList[index], 'materialCode', selectedMaterial.materialNo);
        }
      }
    },

    /** 初始化物料明细的物料信息 */
    async initMaterialDetails() {
      // 为每个物料明细项设置初始物料列表
      for (let i = 0; i < this.formData.materialList.length; i++) {
        const item = this.formData.materialList[i];
        // 为每个物料项创建独立的物料选项数组
        if (!item.materialOptions) {
          this.$set(item, 'materialOptions', []);
        }
      }
    },
    /** 添加物料明细行 */
    addSupply() {
      const newSupply = {
        materialId: undefined,
        materialName: '',
        materialCode: '',
        quantity: null,
        batchNo: '',
        // 为新增项添加独立的物料选项数组
        materialOptions: []
      };
      this.formData.materialList.push(newSupply);

      // 获取索引
      const index = this.formData.materialList.length - 1;
      // 加载默认物料列表
      this.remoteMethod('', index);
    },

    /** 删除物料明细行 */
    removeSupply(index) {
      this.formData.materialList.splice(index, 1);
    },
    /** 获取仓库树数据 */
    async getWarehouseTree() {
      try {
        const params = {
          pageNo: 1,
          pageSize: 1000 // 获取足够多的数据用于构建树
        };
        const res = await WarehouseApi.getWarehousePage(params);
        this.warehouseTree = res.data
      } catch (error) {
        console.error('获取仓库树数据失败:', error);
        this.$modal.msgError('获取仓库树数据失败');
      }
    },

    /** 树节点标准化处理 */
    normalizerW(node) {
      const result = {
        id: node.id,
        label: node.warehouseName,
        children: undefined
      };
      // 只有当children存在且不为undefined且长度大于0时才添加该字段
      if (node.children && node.children.length > 0) {
        result.children = node.children;
      }
      return result;
    },

    /** 部门树节点标准化处理 */
    normalizer(node) {
      // 构建基础对象，确保包含 id, label, children 属性
      const normalizedNode = {
        id: node.id,
        label: node.name,
        children: node.children,
      };
      
      return normalizedNode;
    },

    /** 获取部门列表 */
    async getDeptList() {
      try {
        const response = await listDept();
        this.deptList = this.handleTree(response.data, "id")[0].children;
      } catch (error) {
        console.error('获取部门列表失败', error);
      }
    },

    /** 处理部门选择 */
    deptChange(e) {
      this.formData.deptName = e.name;
    },

    /** 领料人远程搜索方法 */
    async applicantRemoteMethod(query) {
      this.applicantUserLoading = true;
      try {
        const params = {
          pageNo: 1,
          pageSize: 100,
          nickname: query // 根据用户名搜索
        };
        const response = await UserApi.listUser(params);
        this.applicantUserList = response.data.list;
      } catch (error) {
        console.error('搜索领料人失败', error);
        this.applicantUserList = [];
      } finally {
        this.applicantUserLoading = false;
      }
    },

    /** 处理领料人选择 */
    handleApplicantChange(userId) {
      const selectedUser = this.applicantUserList.find(user => user.id === userId);
      if (selectedUser) {
        this.formData.applicantUserName = selectedUser.username;
      } else {
        this.formData.applicantUserName = undefined;
      }
    },

    /** 处理树结构 */
    handleTree(data, id, parentId, children, rootId) {
      id = id || 'id';
      parentId = parentId || 'parentId';
      children = children || 'children';
      rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0;
      // 对源数据深度克隆
      const cloneData = JSON.parse(JSON.stringify(data));
      // 循环所有项
      const treeData = cloneData.filter(father => {
        const branchArr = cloneData.filter(child => {
          // 返回每一项的子级数组
          return father[id] === child[parentId];
        });
        branchArr.length > 0 ? father[children] = branchArr : '';
        // 返回第一层
        return father[parentId] === rootId;
      });
      return treeData !== '' ? treeData : cloneData;
    },

    /** 仓库选择变化时触发 */
    async onWarehouseChange(warehouseId) {
      this.formData.outStoreId = null;
      if (warehouseId) {
        await this.getLocationList(warehouseId.id);
      } else {
        this.locationList = [];
      }
    },

    /** 入库仓库选择变化时触发 */
    async onWarehouseInChange(warehouseId) {
      this.formData.inStoreId = null;
      if (warehouseId) {
        await this.getLocationInList(warehouseId.id);
      } else {
        this.locationInList = [];
      }
    },

    /** 根据仓库ID获取出库库位列表 */
    async getLocationList(warehouseId) {
      try {
        const params = {
          pageNo: 1,
          pageSize: 100,
          warehouseId: warehouseId
        };
        const res = await LocationApi.getLocationPage(params);
        this.locationList = res.data.list;
      } catch (error) {
        console.error('获取库位列表失败:', error);
        this.locationList = [];
      }
    },

    /** 根据仓库ID获取入库库位列表 */
    async getLocationInList(warehouseId) {
      try {
        const params = {
          pageNo: 1,
          pageSize: 100,
          warehouseId: warehouseId
        };
        const res = await LocationApi.getLocationPage(params);
        this.locationInList = res.data.list;
      } catch (error) {
        console.error('获取库位列表失败:', error);
        this.locationInList = [];
      }
    },

    /** 打开弹窗 */
    async open(id, isDetail = false, materialList = null, defaultFormData = null) {
      this.dialogVisible = true;
      this.reset();
      this.isDetailMode = isDetail;
      
      // 加载部门列表
      await this.getDeptList();
      
      // 修改或查看详情时，设置数据
      if (id) {
        this.formLoading = true;
        try {
          const res = await OrderApi.getOrder(id);
          this.formData = res.data;

          // 如果有出库仓库ID，获取对应的库位列表
          if (res.data.outWarehouseId) {
            await this.getLocationList(res.data.outWarehouseId);
          }

          // 如果有入库仓库ID，获取对应的库位列表
          if (res.data.inWarehouseId) {
            await this.getLocationInList(res.data.inWarehouseId);
          }
          
          // 如果有领料人ID，需要显示对应的用户名
          if (res.data.applicantUserId) {
            await this.applicantRemoteMethod(res.data.applicantUserName || '');
          }

          // 初始化物料明细信息
          await this.initMaterialDetails();

          this.dialogTitle = isDetail ? "查看单据详情" : "修改仓库单据";
        } finally {
          this.formLoading = false;
        }
      } else {
        // 加载默认的领料人列表
        await this.applicantRemoteMethod('');
        
        this.dialogTitle = "新增仓库单据";

        // 设置默认表单数据（如果有）
        if (defaultFormData) {
          // 将默认数据合并到表单中
          Object.assign(this.formData, defaultFormData);
          // 标记这些字段为不可编辑
          this.disabledFields = {
            orderType: true,
            sourceType: true,
            sourceTypeName: true,
            businessType: true,
            businessTypeName: true,
            sourceNo: true
          };
        }

        // 如果传入了物料明细数据，设置到表单中
        if (materialList && materialList.length > 0) {
          this.formData.materialList = materialList;

          // 为每个物料项根据materialName调用remoteMethod
          for (let i = 0; i < this.formData.materialList.length; i++) {
            const item = this.formData.materialList[i];
            if (item.materialName) {
              await this.remoteMethod(item.materialName, i);
            } else {
              // 如果没有物料名称，调用空查询获取默认列表
              await this.remoteMethod('', i);
            }

            // 如果有物料名称，尝试匹配物料ID
            if (item.materialName && item.materialOptions && item.materialOptions.length > 0) {
              const matchedMaterial = item.materialOptions.find(m => m.materialName === item.materialName);
              if (matchedMaterial) {
                this.$set(this.formData.materialList[i], 'materialId', matchedMaterial.id);
              }
            }
          }
        }
      }
    },
    /** 提交按钮 */
    async submitForm() {
      // 校验主表
      await this.$refs["formRef"].validate();
      this.formLoading = true;
      try {
        const data = this.formData;
        // 修改的提交
        if (data.id) {
          await OrderApi.updateOrder(data);
          this.$modal.msgSuccess("修改成功");
          this.dialogVisible = false;
          this.$emit('success');
          return;
        }
        // 添加的提交
        delete data.id;
        await OrderApi.createOrder(data);
        this.$modal.msgSuccess("新增成功");
        this.dialogVisible = false;
        this.$emit('success');
      } finally {
        this.formLoading = false;
      }
    },
    /** 表单重置 */
    reset() {
      // 不重置isDetailMode，保持传入的模式状态
      this.formData = {
        id: undefined,
        orderType: 1,
        sourceType: undefined,
        sourceTypeName: undefined,
        sourceNo: undefined,
        businessType: undefined,
        businessTypeName: undefined,
        outWarehouseId: undefined,
        outStoreId: undefined,
        inWarehouseId: undefined,
        inStoreId: undefined,
        applicantUserId: undefined,
        applicantUserName: undefined,
        deptId: undefined,
        deptName: undefined,
        materialList: []
      };
      this.locationList = [];
      this.locationInList = [];
      this.applicantUserList = [];
      this.resetForm("formRef");
    },

    /** 格式化日期为年-月-日格式 */
    formatDate(date) {
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      return `${year}-${month}-${day}`;
    }
  }
};
</script>


<style scoped lang="scss">
:deep(.el-input__inner:disabled),
:deep(.el-select__inner:disabled),
:deep(.el-date-editor .el-input__inner:disabled),
:deep(.el-input.is-disabled .el-input__inner) {
  background-color: #F9F9F9 !important;
  color: #333 !important;
  border-color: #DCDFE6 !important;
}

:deep(.vue-treeselect--disabled) {
  background-color: #F9F9F9 !important;

  .vue-treeselect__control {
    background-color: #F9F9F9 !important;
    color: #333 !important;
  }
}
</style>
